package com.dinim.physics2D;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import com.dinim.graphics.IDrawable;
import com.dinim.graphics.IGraphicsContext;
import com.dinim.object.IObject2D;
import com.dinim.object.Object2D;

public abstract class Aabb implements IDrawable{

    protected double height;
    protected double width;
    protected int lines;
    protected int columns;
    protected double columnWidth;
    protected double lineHeight;
    protected List<IObject2D>[][] aabbMatrix;

    public Aabb(double height, double width, int lines, int columns) {
        this.height = height;
        this.width = width;
        this.lines = lines;
        this.columns = columns;
        
        this.columnWidth = width / columns;
        this.lineHeight = height / lines;
        
        aabbMatrix = new ArrayList[lines][columns];
    }

    public abstract void addObject(IObject2D object);

    public List getObjectGroups(){

        sdlf sd = new sdlf();
        
        List groups = new ArrayList();
        
        for(int i = 0; i < aabbMatrix.length; i++){
            for(int j = 0; j < aabbMatrix[i].length; j++){
                if ((aabbMatrix[i][j] != null) && (aabbMatrix[i][j].size() > 1)){
                    Object[] objss = (aabbMatrix[i][j]).toArray();
                    for(int l1 = 0; l1 < objss.length; l1++){
                        IObject2D object1 = (IObject2D) objss[l1];
                        if(((l1+1) < objss.length)){
                            for(int l2 = l1+1; l2 < objss.length; l2++){
                                //System.out.println("still working...");
                                IObject2D object2 = (IObject2D) objss[l2];
                                ObjectGroup og = new ObjectGroup(object1, object2);
                                if(!groups.contains(og)){
                                    groups.add(og);
                                } else {
                                    //System.out.println("already contains shit!");
                                }
                                //sd.addObjectGroup(object1, object2);
                            }
                        }
                    }
                }
            }
        }

//        Iterator it = groups.iterator();
//        while(it.hasNext()){
//            //System.out.println(it.next());
//            it.next();
//        }
        //System.out.println("---------------------------------------------");
        return groups;
    }

    protected void addObjectToArray(IObject2D object, IBoundingBox2D boundingBox) {
        int y1 = (int)(boundingBox.getTop() / lineHeight);
        int y2 = (int)(boundingBox.getBottom() / lineHeight);
        int x1 = (int)(boundingBox.getLeft() / columnWidth);
        int x2 = (int)(boundingBox.getRight() / columnWidth);
        if(x1>x2){
            int xbuf = x1;
            x1 = x2;
            x2 = xbuf;
        }
        if(y1>y2){
            int ybuf = y1;
            y1 = y2;
            y2 = ybuf;
        }
        for(int i = y1; i <= y2; i++){
            for(int j = x1; j <= x2; j++){
                if ((i < lines) && (j < columns) && (i >= 0) && (j >= 0)) {
                    if(aabbMatrix[i][j] == null){
                        aabbMatrix[i][j] = new ArrayList<IObject2D>();
                    }
                    if(!aabbMatrix[i][j].contains(object)){
                        aabbMatrix[i][j].add(object);
                    }
                }
            }
        }
    }

    public String toString() {
        String str = "";
        for(int i = 0; i < aabbMatrix.length; i++){
            for(int j = 0; j < aabbMatrix[i].length; j++){
                if (aabbMatrix[i][j] != null) {
                    str = str + aabbMatrix[i][j].size() + " ";
                } else {
                    str = str + ". ";
                }
            }
            str = str + "\n";
        }
        return str;
    }

    public void draw(IGraphicsContext gc) {
        gc.drawRectangle(1, 1, (int)width,(int)height);
        for(int i = 0; i < aabbMatrix.length; i++){
            for(int j = 0; j < aabbMatrix[i].length; j++){
                if (aabbMatrix[i][j] != null) {
                    int x1 = (int)Math.round(j * columnWidth);
                    int y1 = (int)Math.round(i * lineHeight);
                    int x2 = (int)Math.round(j * columnWidth + columnWidth);
                    int y2 = (int)Math.round(i * lineHeight + lineHeight);
                    gc.drawRectangle(x1, y1, x2, y2);
                    gc.drawText(""+aabbMatrix[i][j].size(), x1+2, y1+13);
                }
            }
        }
    }
}